package com.fzu.normalservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzu.commonutil.params.DataResult;
import com.fzu.commonutil.params.SelectResult;
import com.fzu.commonutil.util.*;
import com.fzu.commonutil.entity.Company;
import com.fzu.commonutil.entity.Housekeeper;
import com.fzu.commonutil.entity.ServiceType;
import com.fzu.commonutil.entity.User;
import com.fzu.commonutil.mapper.CompanyMapper;
import com.fzu.commonutil.mapper.HousekeeperMapper;
import com.fzu.normalservice.client.ThirdPartyClient;
import com.fzu.normalservice.service.HousekeeperService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzu.normalservice.service.HousekeeperServiceTypeService;
import com.fzu.normalservice.service.ImageService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zyq
 * @since 2023-03-26
 */
@Service
@RequiredArgsConstructor
public class HousekeeperServiceImpl extends ServiceImpl<HousekeeperMapper, Housekeeper> implements HousekeeperService {

    private final HousekeeperMapper housekeeperMapper;
    private final HousekeeperServiceTypeService housekeeperServiceTypeService;
    private final ImageService imageService;
    private final CompanyMapper companyMapper;
    private final RedisUtil redisUtil;
    private final ThirdPartyClient thirdPartyClient;

    @Override
    public PageVO list(Housekeeper housekeeper, Integer pageNum, Integer pageSize) {
        // 构造分页参数
        Page<Housekeeper> pageRequest = new Page<>(pageNum, pageSize);
        // 进行自定义分页查询
        Page<Housekeeper> page = housekeeperMapper.selectPage(pageRequest, housekeeper);
        List<Housekeeper> records = page.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            Set<Integer> companyIds = records.stream().map(Housekeeper::getCompanyId).collect(Collectors.toSet());
            List<Company> companies = companyMapper.selectBatchIds(companyIds);
            Map<Integer, Integer> companyManagerMap = companies.stream().collect(Collectors.toMap(Company::getId, Company::getUserId));
            for (Housekeeper record : records) {
                record.setImageUrlList(imageService.listByHouseKeeperId(record.getId()));
                record.setTypeList(housekeeperServiceTypeService.listByHousekeeperId(record.getId()));
                record.setManagerId(companyManagerMap.get(record.getCompanyId()));
            }
        }
        return PageVO.convert(page);
    }

    @Override
    public void add(Housekeeper housekeeper, User user) {
        Integer role = user.getRole();
        if (!CodeEnum.COMPANY.getCode().equals(role)) {
            throw new ApiException(ErrorEnum.ROLE_ERROR);
        }
        Integer companyId = user.getCompanyId();
        Company company = companyMapper.selectById(companyId);
        if (company == null) {
            throw new ApiException(ErrorEnum.MESSAGE_ERROR);
        }
        housekeeper.setCompanyId(companyId);
        housekeeper.setCompanyName(company.getName());
        List<Integer> typeIdList = housekeeper.getTypeIdList();
        if (CollectionUtils.isEmpty(typeIdList)) {
            throw new ApiException("服务类型不能为空");
        }
        // 获取经纬度并填充
        String address = housekeeper.getProvince() + housekeeper.getCity() + housekeeper.getTown() + housekeeper.getDetail();
        R r = thirdPartyClient.getCoordinate(address);
        Coordinate coordinate = (Coordinate)R.getDataFromR(r, Coordinate.class);
        housekeeper.setLongitude(coordinate.getLng());
        housekeeper.setLatitude(coordinate.getLat());
        housekeeperMapper.insert(housekeeper);
        // 保存服务类型关联关系
        housekeeperServiceTypeService.operate(housekeeper.getId(), housekeeper.getTypeIdList());
        // 保存图片关联关系
        imageService.operateHouseKeeperImage(housekeeper.getId(), housekeeper.getImageUrlList());
        // 记录家政员信息发生变化
        redisUtil.set(RedisKey.HOUSEKEEPER_CHANGE_TAG, 0);
    }

    @Override
    public void update(Housekeeper housekeeper, User user) {
        Integer id = housekeeper.getId();
        Housekeeper entity = super.getById(id);
        if (entity == null) {
            throw new ApiException(ErrorEnum.OBJECT_NOT_FOUND);
        }
        if (!CodeEnum.MANAGER.getCode().equals(user.getRole())) {
            if (user.getCompanyId() == null || !user.getCompanyId().equals(entity.getCompanyId())) {
                throw new ApiException(ErrorEnum.UPDATE_ERROR);
            }
        }
        BeanUtils.copyProperties(housekeeper, entity);
        super.updateById(entity);
        // 更新服务类型关联关系
        housekeeperServiceTypeService.operate(housekeeper.getId(), housekeeper.getTypeIdList());
        // 更新图片关联关系
        imageService.operateHouseKeeperImage(housekeeper.getId(), housekeeper.getImageUrlList());
        // 记录家政员信息发生变化
        redisUtil.set(RedisKey.HOUSEKEEPER_CHANGE_TAG, 0);
    }

    @Override
    public Housekeeper detail(Integer id) {
        Housekeeper housekeeper = super.getById(id);
        housekeeper.setImageUrlList(imageService.listByHouseKeeperId(id));
        List<ServiceType> serviceTypes = housekeeperServiceTypeService.listByHousekeeperId(id);
        List<Integer> typeIds = serviceTypes.stream().map(ServiceType::getId).collect(Collectors.toList());
        housekeeper.setTypeList(housekeeperServiceTypeService.listByHousekeeperId(id));
        housekeeper.setTypeIdList(typeIds);
        return housekeeper;
    }

    @Override
    public DataResult housekeeperData(DataResult result, Integer companyId) {
        List<SelectResult> newUserCountList = housekeeperMapper.sevenDayNewUser(companyId);
        Map<String, Integer> countMap = new HashMap<>(0);
        if (!CollectionUtils.isEmpty(newUserCountList)) {
            countMap = newUserCountList.stream().collect(Collectors.toMap(SelectResult::getTotalDate, SelectResult::getTotal));
        }
        List<String> days = DateUtils.getDays(7);
        List<Integer> counts = new ArrayList<>(7);
        for (String day : days) {
            Integer c = countMap.get(day);
            if (c == null) {
                c = 0;
            }
            counts.add(c);
        }
        result.setHousekeeperData(counts);
        result.setHousekeeperLabel(days);
        LambdaQueryWrapper<Housekeeper> wrapper = new LambdaQueryWrapper<>();
        if (companyId != null) {
            wrapper.eq(Housekeeper::getCompanyId, companyId);
        }
        result.setHousekeeperCount(housekeeperMapper.selectCount(wrapper));
        return result;
    }
}
